#pragma once
#ifndef __DebugRender_h_
#define __DebugRender_h_

#include <OgreCamera.h>
#include <OgreEntity.h>
#include <OgreLogManager.h>
#include <OgreRoot.h>
#include <OgreViewport.h>
#include <OgreSceneManager.h>
#include <OgreRenderWindow.h>
#include <OgreConfigFile.h>

#include <OISEvents.h>
#include <OISInputManager.h>
#include <OISKeyboard.h>
#include <OISMouse.h>

#include <SdkTrays.h>
#include <SdkCameraMan.h>

#include "OgreManualObject.h"
#include "OgreResourceGroupManager.h"
#include "World.h"
#include "Analyzer.h"
#include <vector>

/// Klasa odpowiedzialna za wizualizacje.
class DebugRender : public Ogre::FrameListener, public Ogre::WindowEventListener, public OIS::KeyListener, public OIS::MouseListener, OgreBites::SdkTrayListener
{
public:
	/// Konstruktor.
    DebugRender(void);

	/// Destruktor.
    virtual ~DebugRender(void);

	/// Wywoluje proces renderowania.
    void go(void);

protected:
	/** Rysuje na scenie zadana bryle.
	* @param hull Wskaznik na bryle.
	* @param r Skladowa koloru, kolor czerwony.
	* @param g Skladowa koloru, kolor zielony.
	* @param b Skladowa koloru, kolor niebieski.
	* @param name Nazwa obiektu.
	* @param group Nazwa grupy materialu.
	* @param visible Okresla, czy dana bryla zostanie wyswietlona.
	*/
	void RenderHull(ConvexHull* hull, float r, float g, float b, Ogre::String name, Ogre::String group, bool visible = true);

	/// Inicjuje srodowisko.
    bool setup();

	/// Wyswietla okno konfiguracji srodowiska.
    bool configure(void);

	/// Konfiguruje menagera sceny.
    void chooseSceneManager(void);

	/// Tworzy kamere.
    void createCamera(void);

	/// Tworzy kolekcjonera zdarzen.
    void createFrameListener(void);

	/// Tworzy scene.
	void createScene(void);

	/// Niszczy scene.
    void destroyScene(void);

	/// Tworzy ekrany.
    void createViewports(void);

	/// Konfiguruje menagera zasobow.
    void setupResources(void);

	/// Monituje zasoby.
    void createResourceListener(void);

	/// Laduje zasoby.
    void loadResources(void);

    // Ogre::FrameListener
    virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);

    // OIS::KeyListener
	/// Reaguje na wcisniety klawisz
    virtual bool keyPressed( const OIS::KeyEvent &arg );
	/// Reaguje na zwolniony klawisz
    virtual bool keyReleased( const OIS::KeyEvent &arg );
    // OIS::MouseListener
	/// Reaguje na ruch myszy
    virtual bool mouseMoved( const OIS::MouseEvent &arg );
	/// Reaguje na wcisniety przycisk myszy.
    virtual bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id );
	/// Reaguje na zwolniony przycisk myszy.
    virtual bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id );

    // Ogre::WindowEventListener
    //Adjust mouse clipping area
    virtual void windowResized(Ogre::RenderWindow* rw);
    //Unattach OIS before window shutdown (very important under Linux)
    virtual void windowClosed(Ogre::RenderWindow* rw);

    Ogre::Root *mRoot;
	/// Wskaznik na kamere.
    Ogre::Camera* mCamera;
	/// Wskaznik na menagera sceny.
    Ogre::SceneManager* mSceneMgr;

	/// Wskaznik na stworzone okno.
    Ogre::RenderWindow* mWindow;

	/// Nazwa pliku z zasobami.
    Ogre::String mResourcesCfg;

	/// Nazwa na plig z pluginami.
    Ogre::String mPluginsCfg;

    // OgreBites
    OgreBites::SdkTrayManager* mTrayMgr;
	/// Kontroler kamery.
    OgreBites::SdkCameraMan* mCameraMan;   
	// Panel z detalami.
    OgreBites::ParamsPanel* mDetailsPanel;   // sample details panel
	/// Okresla, czy kursor jest widoczny podczas ladowania srodowiska.
    bool mCursorWasVisible;                  // was cursor visible before dialog appeared
	/// Okresla, czy aplikacja zostala zamknieta.
    bool mShutDown;

    //OIS Input devices
	/// Menadzer we/wy.
    OIS::InputManager* mInputManager;
	/// Wskaznik na mysz.
    OIS::Mouse*    mMouse;
	/// Wskaznik na klawiature.
    OIS::Keyboard* mKeyboard;

	/// Lista obiektow do narysowania.
	std::vector<Ogre::ManualObject*> objToRender;
	/// Lista materialow
	std::vector<Ogre::MaterialPtr> materials;

	/// Indeks, od ktorego wyliczane sa wyznaczone bryly
	int startIndex;
	/// Indeks obecnie wybranej bryly
	int currentIndex;

	Ogre::ColourValue GREEN, YELLOW, RED, BLUE;


};

#endif // #ifndef __DebugRender_h_